package com.kexio.core.security.service.impl;

import com.kexio.core.security.context.UserContext;
import com.kexio.core.security.context.UserContextHolder;
import com.kexio.core.security.service.RbacService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 默认RBAC权限控制服务实现
 *
 * @author Kexio Team
 * @since 1.0.0
 */
public class DefaultRbacService implements RbacService {

    private static final Logger log = LoggerFactory.getLogger(DefaultRbacService.class);

    @Override
    public boolean hasRole(Long userId, String role) {
        if (userId == null || role == null || role.trim().isEmpty()) {
            return false;
        }

        // TODO: 实际应用中应该从数据库或缓存查询用户角色
        List<String> userRoles = getUserRoles(userId);
        return userRoles != null && userRoles.contains(role);
    }

    @Override
    public boolean hasRole(String role) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.hasRole(role);
    }

    @Override
    public boolean hasAnyRole(Long userId, String... roles) {
        if (userId == null || roles == null || roles.length == 0) {
            return false;
        }

        List<String> userRoles = getUserRoles(userId);
        if (userRoles == null || userRoles.isEmpty()) {
            return false;
        }

        for (String role : roles) {
            if (userRoles.contains(role)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasAnyRole(String... roles) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.hasAnyRole(roles);
    }

    @Override
    public boolean hasPermission(Long userId, String permission) {
        if (userId == null || permission == null || permission.trim().isEmpty()) {
            return false;
        }

        // TODO: 实际应用中应该从数据库或缓存查询用户权限
        List<String> userPermissions = getUserPermissions(userId);
        return userPermissions != null && userPermissions.contains(permission);
    }

    @Override
    public boolean hasPermission(String permission) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.hasPermission(permission);
    }

    @Override
    public boolean hasAnyPermission(Long userId, String... permissions) {
        if (userId == null || permissions == null || permissions.length == 0) {
            return false;
        }

        List<String> userPermissions = getUserPermissions(userId);
        if (userPermissions == null || userPermissions.isEmpty()) {
            return false;
        }

        for (String permission : permissions) {
            if (userPermissions.contains(permission)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasAnyPermission(String... permissions) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.hasAnyPermission(permissions);
    }

    @Override
    public boolean hasAllPermissions(Long userId, String... permissions) {
        if (userId == null || permissions == null || permissions.length == 0) {
            return false;
        }

        List<String> userPermissions = getUserPermissions(userId);
        if (userPermissions == null || userPermissions.isEmpty()) {
            return false;
        }

        for (String permission : permissions) {
            if (!userPermissions.contains(permission)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasAllPermissions(String... permissions) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.hasAllPermissions(permissions);
    }

    @Override
    public List<String> getUserRoles(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }

        // TODO: 实际应用中应该从数据库或缓存查询用户角色
        log.warn("默认实现：getUserRoles(userId={}) 需要业务系统提供具体实现", userId);
        
        // 提供一些演示数据
        if (userId.equals(1L)) {
            return Arrays.asList("admin", "user");
        } else if (userId.equals(2L)) {
            return Arrays.asList("user");
        }
        
        return Collections.singletonList("user");
    }

    @Override
    public List<String> getUserPermissions(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }

        // TODO: 实际应用中应该从数据库或缓存查询用户权限
        log.warn("默认实现：getUserPermissions(userId={}) 需要业务系统提供具体实现", userId);
        
        // 提供一些演示数据
        List<String> permissions = new ArrayList<>();
        
        if (userId.equals(1L)) {
            // 管理员权限
            permissions.addAll(Arrays.asList(
                "system:user:list", "system:user:add", "system:user:edit", "system:user:delete",
                "system:role:list", "system:role:add", "system:role:edit", "system:role:delete",
                "system:menu:list", "system:menu:add", "system:menu:edit", "system:menu:delete",
                "system:dept:list", "system:dept:add", "system:dept:edit", "system:dept:delete"
            ));
        } else if (userId.equals(2L)) {
            // 普通用户权限
            permissions.addAll(Arrays.asList(
                "system:user:list", "system:role:list"
            ));
        } else {
            // 默认权限
            permissions.add("system:user:list");
        }
        
        return permissions;
    }

    @Override
    public boolean isAdmin(Long userId) {
        if (userId == null) {
            return false;
        }

        // 检查是否拥有管理员角色
        return hasRole(userId, "admin") || hasRole(userId, "ADMIN") || hasRole(userId, "administrator");
    }

    @Override
    public boolean isAdmin() {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return context.isAdmin();
    }

    @Override
    public boolean canAccess(Long userId, String resource, String action) {
        if (userId == null || resource == null || action == null) {
            return false;
        }

        // 超级管理员拥有所有权限
        if (isAdmin(userId)) {
            return true;
        }

        // 构造权限标识
        String permission = resource + ":" + action;
        
        // 检查是否拥有精确权限
        if (hasPermission(userId, permission)) {
            return true;
        }

        // 检查是否拥有资源的全部权限
        String allPermission = resource + ":*";
        if (hasPermission(userId, allPermission)) {
            return true;
        }

        // 检查是否拥有全局权限
        if (hasPermission(userId, "*")) {
            return true;
        }

        return false;
    }

    @Override
    public boolean canAccess(String resource, String action) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return canAccess(context.getUserId(), resource, action);
    }

    @Override
    public boolean canOperateData(Long userId, String dataType, Long dataId, String action) {
        if (userId == null || dataType == null || dataId == null || action == null) {
            return false;
        }

        // 超级管理员拥有所有数据权限
        if (isAdmin(userId)) {
            return true;
        }

        // TODO: 实际应用中应该根据数据权限规则进行判断
        // 这里提供一个简单的实现：用户只能操作自己的数据
        log.warn("默认实现：canOperateData 需要业务系统提供具体实现");
        
        // 如果是操作用户数据，只能操作自己的数据
        if ("user".equals(dataType) || "USER".equals(dataType)) {
            return userId.equals(dataId);
        }
        
        // 其他数据类型，检查是否有相应权限
        return canAccess(userId, dataType, action);
    }

    @Override
    public boolean canOperateData(String dataType, Long dataId, String action) {
        UserContext context = UserContextHolder.getContext();
        if (context == null) {
            return false;
        }
        return canOperateData(context.getUserId(), dataType, dataId, action);
    }
}
